﻿using AutoMapper;
using DFGK.WMS.Common;
using DFGK_WMS.Context;
using DFGK_WMS.IRepository;
using DFGK_WMS.Model.DTO;
using DFGK_WMS.Model.Enum;
using DFGK_WMS.Model.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.IdentityModel.Logging;
using NetTaste;
using NPOI.POIFS.Crypt.Dsig;
using NPOI.SS.Formula.Functions;
using NPOI.SS.Formula.PTG;
using NPOI.XSSF.Streaming.Values;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;

namespace DFGK_WMS.Repository
{
    public class TCellRepository : BaseRepository<TCell>, ITCellRepository
    {
        public TCellRepository(DFGK_DB context, IMapper mapper) : base(context, mapper)
        {
        }

        /// <summary>
        /// 仓位左侧树形显示
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public List<Menuitem> GetMenuitem()
        {
            var wlist = Context.TWarehouses.AsNoTracking().ToList();

            return wlist.Select(item => new Menuitem
            {
                label = item.Name,
                value = item.Id,
                icon = item.Code,
                alias = "wh",
                children = GetAreaMenuitem(item.Id)
            }).ToList();
        }

        public List<Menuitem> GetAreaMenuitem(int wid)
        {
            var list = Context.TAreas.AsNoTracking().Where(x => x.WhId == wid).ToList();
            return list.Select(x => new Menuitem
            {
                label = x.Name,
                value = x.Id,
                icon = x.Code,
                alias = "area",
                children = GetShelfMenuitem(x.Id)
            }).ToList();
        }

        public List<Menuitem> GetShelfMenuitem(int aid)
        {
            var list = Context.TShelves.Where(x => x.AreaId == aid);
            return list.Select(x => new Menuitem
            {
                label = x.Name,
                value = x.Id,
                icon = x.Code,
                alias = "shelf",
                children = null
            }).ToList();
        }

        public List<Menuitem> GetRowMenuItem()
        {
            List<Menuitem> menuList = new List<Menuitem>();
            foreach (var warehouse in Context.TWarehouses.ToList())
            {
                Menuitem menuitem = new Menuitem()
                {
                    label = warehouse.Name,
                    value = warehouse.Id,
                    icon = warehouse.Code,
                    alias = "wh",
                    children = null

                };

                List<Menuitem> areaMenuList = new List<Menuitem>();
                foreach (var area in Context.TAreas.Where(it => it.WhId == warehouse.Id).ToList())
                {
                    Menuitem areaMenu = new Menuitem()
                    {
                        label = area.Name,
                        value = area.Id,
                        icon = area.Code,
                        alias = "area",
                        children = null

                    };
                    List<Menuitem> rowMenuList = new List<Menuitem>();
                    foreach (var row in Context.TRows.Where(it => it.AreaId == area.Id).ToList())
                    {
                        rowMenuList.Add(new Menuitem()
                        {
                            label = row.RowName,
                            value = row.Id,
                            icon = row.RowId.ToString(),
                            alias = "row",
                            children = null
                        });
                    }
                    areaMenu.children = rowMenuList;

                    areaMenuList.Add(areaMenu);

                }
                menuitem.children = areaMenuList;

                menuList.Add(menuitem);
            }

            return menuList;
        }


        /// <summary>
        /// 添加仓位
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public bool AddTcell(TCellDto obj, out string message)
        {
            message = "";
            try
            {
                var cobj = Context.TCells.AsNoTracking().FirstOrDefault(x => x.Code == obj.Code);
                if (cobj != null)
                {
                    message = "编码已存在！";
                    return false;
                }
                TCell tcell = new TCell();
                tcell = Mapper.Map<TCell>(obj);
                tcell.CreateUserId = obj.NowUserId;
                tcell.CreateUserName = obj.NowUserRealName;
                tcell.CreateDate = DateTime.Now;
                tcell.ModifyUserId = obj.NowUserId;
                tcell.ModifyUserName = obj.NowUserRealName;
                tcell.ModifyDate = DateTime.Now;
                //库房
                var wobj = Context.TWarehouses.Find(obj.WhId);
                if (wobj != null && wobj.Status == 1)
                {
                    tcell.WhName = wobj.Name;
                    tcell.WhCode = wobj.Code;
                }
                else
                {
                    message = "库房不存在或已被禁用！";
                    return false;
                }
                //库区
                var aobj = Context.TAreas.Find(obj.AreaId);
                if (aobj != null && aobj.Status == 1)
                {
                    tcell.AreaName = aobj.Name;
                    tcell.AreaCode = aobj.Code;
                }
                else
                {
                    message = "库区不存在或已被禁用！";
                    return false;
                }
                //货架
                var sobj = Context.TShelves.Find(obj.ShelfId);
                if (sobj != null && sobj.Status == 1)
                {
                    tcell.ShelfCode = sobj.Code;
                    tcell.ShelfName = sobj.Name;
                    tcell.RoutewayId = sobj.RoutewayId.GetValueOrDefault();
                }
                else
                {
                    message = "货架不存在或已被禁用！";
                    return false;
                }
                //逻辑分区
                var dicobj = Context.TDictItems.FirstOrDefault(x => x.ItemCode == obj.LogicalPartCode);
                if (dicobj != null)
                {
                    tcell.LogicalPartName = dicobj.ItemName;
                }
                tcell.DistanceValue = Convert.ToDecimal(Math.Sqrt(Math.Pow(tcell.LayerNo, 2) + Math.Pow(tcell.ColumnNo, 2) + Math.Pow(tcell.LineNo - 1, 2)));
                int lineNO = 0;
                int layerNO = tcell.LayerNo;
                int columnNO = tcell.ColumnNo;
                if (tcell.LineNo < 7)
                {
                    lineNO = tcell.LineNo;
                }
                else
                {
                    lineNO = tcell.LineNo + tcell.DepthIndex + (tcell.LineNo - 7);
                }
                tcell.Erpcode = aobj.Code + "-" + lineNO.ToString("00") + layerNO.ToString("00") + columnNO.ToString("00");
                Context.TCells.Add(tcell);
                return Context.SaveChanges() > 0;
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 修改仓位
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public bool UpdateTcell(TCellDto obj, out string message)
        {
            message = "";
            try
            {
                var cobj = Context.TCells.AsNoTracking().FirstOrDefault(x => x.Id != obj.Id && x.Code == obj.Code);
                if (cobj != null)
                {
                    message = "编码已存在！";
                    return false;
                }
                TCell tcell = new TCell();
                tcell = Mapper.Map<TCell>(obj);
                tcell.ModifyUserId = obj.NowUserId;
                tcell.ModifyUserName = obj.NowUserRealName;
                tcell.ModifyDate = DateTime.Now;
                //库房
                var wobj = Context.TWarehouses.Find(obj.WhId);
                if (wobj != null && wobj.Status == 1)
                {
                    tcell.WhName = wobj.Name;
                    tcell.WhCode = wobj.Code;
                }
                else
                {
                    message = "库房不存在或已被禁用！";
                    return false;
                }
                //库区
                var aobj = Context.TAreas.Find(obj.AreaId);
                if (aobj != null && aobj.Status == 1)
                {
                    tcell.AreaName = aobj.Name;
                    tcell.AreaCode = aobj.Code;
                }
                else
                {
                    message = "库区不存在或已被禁用！";
                    return false;
                }
                //逻辑分区
                var dicobj = Context.TDictItems.FirstOrDefault(x => x.ItemCode == obj.LogicalPartCode);
                if (dicobj != null)
                {
                    tcell.LogicalPartName = dicobj.ItemName;
                }
                //货架
                var sobj = Context.TShelves.Find(obj.ShelfId);
                if (sobj != null && sobj.Status == 1)
                {
                    tcell.ShelfCode = sobj.Code;
                    tcell.ShelfName = sobj.Name;
                }
                else
                {
                    message = "货架不存在或已被禁用！";
                    return false;
                }
                tcell.DistanceValue = Convert.ToDecimal(Math.Sqrt(Math.Pow(tcell.LayerNo, 2) + Math.Pow(tcell.ColumnNo, 2) + Math.Pow(tcell.LineNo - 1, 2)));
                int lineNO = 0;
                int layerNO = tcell.LayerNo;
                int columnNO = tcell.ColumnNo;
                if (tcell.LineNo < 7)
                {
                    lineNO = tcell.LineNo;
                }
                else
                {
                    lineNO = tcell.LineNo + tcell.DepthIndex + (tcell.LineNo - 7);
                }
                tcell.Erpcode = aobj.Code + "-" + lineNO.ToString("00") + layerNO.ToString("00") + columnNO.ToString("00");
                Context.TCells.Update(tcell);
                return Context.SaveChanges() > 0;
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="uid"></param>
        /// <returns></returns>
        public bool DelTcell(int uid)
        {
            try
            {
                var del = Context.TCells.Find(uid);
                if (del != null)
                {
                    Context.TCells.Remove(del);
                    return Context.SaveChanges() > 0;
                }
                return false;
            }
            catch (Exception)
            {
                throw;
            }
        }

        // <summary>
        /// 获取库房(仓库)信息
        /// </summary>
        /// <returns></returns>
        public List<TWarehouse> GetTwarehouseList()
        {
            try
            {
                return Context.TWarehouses.ToList();
            }
            catch (Exception)
            {
                throw;
            }
        }

        // <summary>
        /// 获取库区信息
        /// </summary>
        /// <returns></returns>
        public List<TArea> GetAreaList()
        {
            try
            {
                return Context.TAreas.ToList();
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 根据id获取数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public TCell GetTcellById(int id)
        {
            try
            {
                return Context.TCells.Find(id);
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 批量设置
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public bool UpdateSetUp(Tcellll obj)
        {
            using (var trans = Context.Database.BeginTransaction())
            {
                try
                {
                    if (obj.Id == null)
                    {
                        return false;
                    }
                    foreach (var item in obj.Id)
                    {
                        var res = Context.TCells.AsNoTracking().FirstOrDefault(p => p.Id == item);
                        if (res is null)
                        {
                            return false;
                        }
                        res.LogicalPartCode = obj.LogicalPartCode;
                        res.LogicalPartName = obj.LogicalPartName;
                        Context.TCells.Update(res);
                        Context.SaveChanges();

                    }
                    Context.SaveChanges();
                    trans.Commit();
                    return true;
                }
                catch (Exception)
                {
                    trans.Rollback();
                    throw;
                }
            }

        }

        /// <summary>
        /// 递归显示库房库区货架
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public List<Menuitem> GetWarAreaShellList()
        {
            var wlist = Context.TWarehouses.AsQueryable();

            return GetWarAreaShellList(wlist.ToList());
        }

        /// <summary>
        /// 库房
        /// </summary>
        /// <param name="wlist"></param>
        /// <returns></returns>
        public List<Menuitem> GetWarAreaShellList(List<TWarehouse> wlist)
        {
            //var alist=Context.TAreas.AsQueryable();
            //var slist=Context.TShelves.AsQueryable();
            return wlist.Select(x => new Menuitem
            {
                value = x.Id,
                label = x.Name,
                alias = "wh",
                children = GetWarAreaShellList(x.Id)
            }).ToList();
        }

        /// <summary>
        /// 库区
        /// </summary>
        /// <param name="wid"></param>
        /// <returns></returns>
        public List<Menuitem> GetWarAreaShellList(int wid)
        {
            var alist = Context.TAreas.Where(x => x.WhId == wid).ToList();
            return alist.Select(x => new Menuitem
            {
                value = x.Id,
                label = x.Name,
                alias = "area",
                children = GetWarAreaShellList(x.Code)
            }).ToList();
        }

        /// <summary>
        /// 货架
        /// </summary>
        /// <param name="wid"></param>
        /// <returns></returns>
        public List<Menuitem> GetWarAreaShellList(string acode)
        {
            var slist = Context.TShelves.Where(x => x.AreaCode == acode).ToList();
            return slist.Select(x => new Menuitem
            {
                value = x.Id,
                label = x.Name,
                alias = "shelf",
                children = null
            }).ToList();
        }

        /// <summary>
        /// 列表显示
        /// </summary>
        /// <param name="logicalPartCode"></param>
        /// <param name="fullStatus"></param>
        /// <param name="status"></param>
        /// <param name="cname"></param>
        /// <param name="whid"></param>
        /// <param name="areid"></param>
        /// <param name="sheid"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="totalCount"></param>
        /// <returns></returns>
        public List<TCell> GetCellList(string logicalPartCode, int fullStatus, int status, string cname, int whid, int areid, int sheid, int pageIndex, int pageSize, out int totalCount)
        {
            var clist = Context.TCells.AsQueryable().ToList();
            //逻辑分区
            if (!string.IsNullOrEmpty(logicalPartCode))
            {
                clist = clist.Where(x => x.LogicalPartCode == logicalPartCode).ToList();
            }
            //仓位状态
            if (fullStatus < 3)
            {
                clist = clist.Where(x => x.FullStatus == fullStatus).ToList();
            }
            //状态
            if (status < 8)
            {
                clist = clist.Where(x => x.Status == status).ToList();
            }
            //仓位名称
            if (!string.IsNullOrEmpty(cname))
            {
                clist = clist.Where(x => x.Name.Contains(cname)).ToList();
            }
            //库房
            if (whid != 0)
            {
                clist = clist.Where(x => x.WhId == whid).ToList();
            }
            //库区
            if (areid != 0)
            {
                clist = clist.Where(x => x.AreaId == areid).ToList();
            }
            //货架
            if (sheid != 0)
            {
                clist = clist.Where(x => x.ShelfId == sheid).ToList();
            }
            totalCount = clist.Count();
            return clist.OrderBy(x => x.CreateDate).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
        }

        /// <summary>
        /// 获取全部仓位
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public List<TCell> GetAllCellList()
        {
            try
            {
                return Context.TCells.AsQueryable().ToList();
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 批量添加仓位
        /// </summary>
        /// <param name="cellCreateBodyDTO"></param>
        /// <returns></returns>
        public bool BatchCreateCell(CellCreateBodyDTO cellCreateBodyDTO, out string message)
        {
            message = "";
            var dictItem = Context.TDictItems.AsNoTracking().Where(d => d.Id == cellCreateBodyDTO.CellTypeId).FirstOrDefault();
            if (dictItem == null)
            {
                message = "仓位类型不存在";
                return false;
            }
            List<TCell> cellList = new List<TCell>();
            var warehouse = Context.TWarehouses.AsNoTracking().Where(w => w.Id == cellCreateBodyDTO.WhId && w.Status == 1).FirstOrDefault();
            if (warehouse == null)
            {
                message = "库房不存在";
                return false;
            }
            var area = Context.TAreas.AsNoTracking().Where(a => a.Id == cellCreateBodyDTO.AreaId && a.Status == 1).FirstOrDefault();
            if (area == null)
            {
                message = "库区不存在";
                return false;
            }
            List<TShelf> shelves = Context.TShelves.AsNoTracking().Where(s => s.WhId == cellCreateBodyDTO.WhId && s.AreaId == cellCreateBodyDTO.AreaId && s.Status == 1 && cellCreateBodyDTO.ShelfIds.Contains(s.Id)).ToList();
            if (shelves == null || shelves.Count == 0)
            {
                message = "货架不存在";
                return false;
            }
            //逻辑分区
            var defaultLogicPart = Context.TDictItems.AsNoTracking().Where(d => d.IsDefault == true && d.TypeCode == "LogicPartType").FirstOrDefault();

            foreach (var shelf in shelves)
            {
                int lineNO = shelf.Number.GetValueOrDefault();
                if (lineNO <= 0)
                {
                    message = shelf.Name + "排号不正确";
                    return false;
                }
                var rowLines = Context.TRows.Where(it => it.WhId == shelf.WhId && it.AreaId == shelf.AreaId && it.ShelfId == shelf.Id)
                    .OrderBy(it => it.ActualityDepthIndex)
                    // .Select(it=>it.ActualityDepthIndex)
                    .ToList();
                if (rowLines == null || rowLines.Count == 0)
                {
                    message = $"{shelf.WhName}库房{shelf.AreaName}库区{shelf.Name}货架排位表为空";
                    return false;
                }
                if (rowLines.Count != shelf.Depth)
                {
                    message = "生成排数和深度不一致";
                    return false;
                }
                int maxDepth = shelf.Depth.GetValueOrDefault();

                for (int layerIndex = 1; layerIndex <= cellCreateBodyDTO.MaxLayer; layerIndex++)
                {
                    for (int columnIndex = 1; columnIndex <= cellCreateBodyDTO.MaxColumn; columnIndex++)
                    {
                        //每列所有深度
                        string rowGroup = $"{lineNO}_{columnIndex}_{layerIndex}_{shelf.Name}_{shelf.AreaCode}_{shelf.WhName}";
                        for (int depthIndex = 0; depthIndex < maxDepth; depthIndex++)
                        {
                            bool isMaxDepth = depthIndex == maxDepth - 1;
                            var depthName = depthIndex == 0 ? "" :
                                                    depthIndex == 1 ? "2深位" :
                                                    depthIndex == 2 ? "3深位" :
                                                    depthIndex == 3 ? " 4深位" :
                                                    depthIndex == 4 ? "5深位" : "未知";
                            string name = string.Format("{0}排{1}列{2}层{3}{4}库区", lineNO.ToString(), columnIndex.ToString(), layerIndex.ToString(), depthName, area.Code);
                            string cellCode = string.Format("Cell:{0}_{1}_{2}_{3}_{4}", lineNO.ToString(), columnIndex.ToString(), layerIndex.ToString(), depthIndex.ToString(), area.Code);
                            int erpLineNO = lineNO;
                            string erpCode = area.Code + "-" + erpLineNO.ToString("00") + layerIndex.ToString("00") + columnIndex.ToString("00") + depthIndex.ToString("00");
                            int heightType = (int)EmHeightType.H2300;
                            if (layerIndex == 1 || layerIndex == 2)
                            {
                                heightType = (int)EmHeightType.H2300;
                            }
                            else if (layerIndex == 3)
                            {
                                heightType = (int)EmHeightType.H1600;
                            }
                            else
                            {
                                heightType = (int)EmHeightType.H1150;
                            }

                            //实际显示排
                            TRow actuallRow = rowLines[depthIndex];

                            int actualLine = actuallRow.RowId;
                            string actualName = string.Format("{0}排{1}列{2}层{3}库区", actualLine.ToString(), columnIndex.ToString(), layerIndex.ToString(), area.Code);
                            string actualCellCode = string.Format("Cell:{0}_{1}_{2}_{3}", actualLine.ToString(), columnIndex.ToString(), layerIndex.ToString(), area.Code);
                            string actualRowName = actuallRow.RowName;

                            TCell cell = new TCell
                            {
                                Code = cellCode,
                                Name = name,
                                WhId = warehouse.Id,
                                WhName = warehouse.Name,
                                AreaId = area.Id,
                                AreaName = area.Name,
                                LineNo = lineNO,
                                LayerNo = layerIndex,
                                ColumnNo = columnIndex,
                                DepthIndex = depthIndex,
                                IsLock = false,
                                Status = (int)EmCellStatus.Normal,
                                IsMaxDepth = isMaxDepth,
                                FullStatus = 0,
                                BusinessType = 0,
                                RoutewayId = shelf.RoutewayId.GetValueOrDefault(),
                                CreateDate = DateTime.Now,
                                ShelfId = shelf.Id,
                                ShelfCode = shelf.Code,
                                ShelfName = shelf.Name,
                                CellType = (int)EmCellType.Normal,
                                Erpcode = erpCode,
                                DistanceValue = Convert.ToDecimal(Math.Sqrt(Math.Pow(layerIndex, 2) + Math.Pow(columnIndex, 2) + Math.Pow(lineNO - 1, 2))),
                                LogicalPartCode = defaultLogicPart == null ? "" : defaultLogicPart.ItemCode,
                                LogicalPartName = defaultLogicPart == null ? "" : defaultLogicPart.ItemName,
                                HeightType = heightType,
                                AreaCode = area.Code,
                                WhCode = warehouse.Code,
                                ActualLine = actualLine,
                                ActualCellName = actualName,
                                ActualCellCode = actualCellCode,
                                ActualRowName = actualRowName,
                                Remark = rowGroup
                            };
                            cellList.Add(cell);
                        }
                    }
                }
            }
            if (cellList == null || cellList.Count == 0)
            {
                return false;
            }
            bool result = false;
            using (var trans = Context.Database.BeginTransaction())
            {
                try
                {
                    foreach (var cell in cellList)
                    {
                        var count = Context.TCells.AsNoTracking().Where(c => c.WhId == warehouse.Id && c.AreaId == area.Id && c.ShelfId == cell.ShelfId && c.Code == cell.Code).Count();
                        if (count > 0)
                        {
                            continue;
                        }
                        Context.TCells.Add(cell);
                        Context.SaveChanges();
                    }
                    foreach (var shelf in shelves)
                    {
                        int cellCount = Context.TCells.AsNoTracking().Where(c => c.ShelfId == shelf.Id && c.Status == (int)EmCellStatus.Normal).Count();
                        int disabledCellCount = Context.TCells.AsNoTracking().Where(c => c.ShelfId == shelf.Id && c.Status == 0).Count();
                        shelf.CellCount = cellCount;
                        shelf.DisabledCellCount = disabledCellCount;
                        Context.TShelves.Update(shelf);
                        Context.SaveChanges();
                    }

                    trans.Commit();
                    return true;
                }
                catch (Exception)
                {
                    trans.Rollback();
                    throw;
                }
            }
        }

        /// <summary>
        /// 分配仓位
        /// </summary>
        /// <param name="srcStation"></param>
        /// <param name="materialId"></param>
        /// <param name="materialKeyId"></param>
        /// <param name="qualityState"></param>
        /// <param name="heightType"></param>
        /// <param name="errorMsg"></param>
        /// <param name="logicalPartCode"></param>
        /// <returns></returns>
        public TCell AllocateCell(TStation srcStation, int materialId, int materialKeyId, int? qualityState, int heightType, out string errorMsg, string logicalPartCode = "")
        {
            errorMsg = "";
            if (materialId <= 0 || materialKeyId <= 0)
            {
                return null;
            }
            TCell allotCell = null;
            try
            {
                TDictItem commonlogicalPartType = Context.TDictItems.AsNoTracking().Where(t => t.TypeCode == "LogicPartType" && t.ItemCode == "Common").FirstOrDefault();
                bool hasCell = false;
                int waitIndex = 0;
                string lineOrder = "ASC";
                do
                {
                    var routewayQuery = Context.TRouteways.AsNoTracking().ToList(); //获取所有巷道
                    var cellQuery = Context.TCells.AsNoTracking().ToList(); //获取所以仓位
                    var inventoryQuery = Context.TInventory.AsNoTracking().ToList(); //获取库存数据
                    var shelves = Context.TShelves.AsNoTracking().ToList(); // 获取所有货架
                    var areaQuery = Context.TAreas.AsNoTracking().ToList(); //获取所有库区
                    if (srcStation.WhId > 0) //库房id不等于空的话会根据库房id去筛选
                    {
                        areaQuery = areaQuery.Where(a => a.WhId == srcStation.WhId).ToList(); //获取库房的所有库区
                        routewayQuery = routewayQuery.Where(zw => zw.WhId == srcStation.WhId).ToList();
                        cellQuery = cellQuery.Where(zw => zw.WhId == srcStation.WhId).ToList();
                        inventoryQuery = inventoryQuery.Where(zw => zw.WarehouseId == srcStation.WhId).ToList();
                        shelves = shelves.Where(s => s.WhId == srcStation.WhId).ToList();
                    }
                    List<TRouteway> routewayList = routewayQuery.Where(r => r.Status == 1).ToList();//查询出可以用的巷道
                    var shelvesList = shelves.Where(s => s.Status == 1).ToList(); //查询出可用的货架
                    if (shelvesList == null || shelvesList.Count <= 0)
                    {
                        errorMsg = "无可用货架";
                        return null;
                    }
                    var areasList = areaQuery.Where(a => a.Status == 1).ToList();

                    if (areasList == null || areasList.Count <= 0)
                    {
                        errorMsg = "无可用库区";
                        return null;
                    }

                    if (routewayList != null && routewayList.Count > 0)
                    {
                        List<int> enabledRoutewayIds = routewayList.Select(t => t.Id).ToList();//只取巷道id
                        List<int> enabledShelves = shelvesList.Select(t => t.Id).ToList();//只取货架id
                        List<int> enabledarrea = areasList.Select(t => t.Id).ToList();//只取库区id
                        List<int> routewayIds = cellQuery.Where(t => t.Status == (int)EmCellStatus.Normal && t.BusinessType == 0 && t.IsLock == false && t.FullStatus == 0 && enabledRoutewayIds.Contains((int)t.RoutewayId) && enabledShelves.Contains(t.ShelfId) && enabledarrea.Contains(t.AreaId)).Select(t => t.RoutewayId).Distinct().ToList(); //只取巷道id

                        if (routewayIds == null || routewayIds.Count == 0)
                        {
                            logicalPartCode = commonlogicalPartType == null ? "" : commonlogicalPartType.ItemCode;
                            routewayIds = cellQuery.Where(t => t.Status == (int)EmCellStatus.Normal && t.BusinessType == 0 && t.IsLock == false && t.FullStatus == 0 && enabledRoutewayIds.Contains(t.RoutewayId) && enabledShelves.Contains(t.ShelfId) && enabledarrea.Contains(t.AreaId)).Select(t => t.RoutewayId).Distinct().ToList();
                        }
                        // 从新赋值一下最新的巷道
                        if (routewayIds != null && routewayIds.Count > 0)
                        {
                            routewayList = routewayList.Where(t => routewayIds.Contains(t.Id)).ToList();
                        }
                    }
                    if (routewayList == null || routewayList.Count == 0)
                    {
                        errorMsg = "无可用巷道";
                        return null;
                    }

                    hasCell = true;

                    //只取巷道编号
                    List<string> routewayCodes = routewayList.OrderBy(t => t.DisplayOrder).Select(t => t.Code).ToList();
                    if (lineOrder == "DESC")
                    {
                        routewayCodes = routewayList.OrderByDescending(t => t.DisplayOrder).Select(t => t.Code).ToList();
                    }

                    List<int?> rwIds = routewayList.Select(t => (int?)t.Id).ToList();
                    //找到此巷道同种物料同批次的仓位
                    var depthCellQuery = (from cell in cellQuery
                                          join inv in inventoryQuery
                                          on cell.Id equals inv.LocationId
                                          where rwIds.Contains(cell.RoutewayId)
                                          && inv.MaterialId == materialId
                                          && inv.MaterialKeyId == materialKeyId
                                          && cell.Status == (int)EmCellStatus.Normal
                                          && cell.IsLock == false && inv.Status == 1
                                          && cell.BusinessType == 0
                                          select cell
                                         );


                    //var disCell = depthCellQuery.Select(s => new Pcl(s.LineNo, s.LayerNo, s.ColumnNo)).Distinct();
                    //找出同种物料同批次的仓位的 所有同一排同一列同一层的所有深位的仓位
                    //var lineNoList = depthCellQuery.Select(s=>s.LineNo);
                    //var layerNoList = depthCellQuery.Select(s=>s.LayerNo);
                    //var columnNoList = depthCellQuery.Select(s=>s.ColumnNo);
                    //获取同物料同批次的仓位排层列
                    //depthCellQuery = cellQuery.Where(s => disCell.Any(d => d == new Pcl(s.LineNo, s.LayerNo, s.ColumnNo)));
                    depthCellQuery = GetCellByCell(depthCellQuery.ToList()).Distinct();

                    var depthLockCellQuery = (from cell in cellQuery
                                              join inv in inventoryQuery
                                              on cell.Id equals inv.LocationId
                                              where rwIds.Contains(cell.RoutewayId)
                                              && inv.MaterialId == materialId
                                              && inv.MaterialKeyId == materialKeyId
                                              && (cell.Status != (int)EmCellStatus.Normal
                                              || cell.IsLock == true || inv.Status != 1)
                                              select cell
                                        );
                    // 根据条件先查询出全部的仓位
                    var celllist = cellQuery.Where(t => t.Status == (int)EmCellStatus.Normal && t.FullStatus == 0 && t.IsLock == false && t.BusinessType == 0 && rwIds.Contains(t.RoutewayId));

                    //筛选出来能用需要使用仓位
                    celllist = celllist.Where(t => depthCellQuery.Where(dc => dc.LayerNo == t.LayerNo && dc.LineNo == t.LineNo && dc.ColumnNo == t.ColumnNo).Any());

                    //把不能用的仓位筛选掉
                    celllist = celllist.Where(t => !depthLockCellQuery.Where(dc => dc.LayerNo == t.LayerNo && dc.LineNo == t.LineNo && dc.ColumnNo == t.ColumnNo).Any()).ToList();
                    //if (!string.IsNullOrEmpty(logicalPartCode))
                    //{
                    //    celllist = celllist.Where(t => t.LogicalPartCode == logicalPartCode).ToList();
                    //}
                    //优先找同种物料、距离最短、深度最深的货位
                    allotCell = celllist.OrderByDescending(c => c.DepthIndex)
                                .ThenBy(c => c.LineNo)
                                .ThenBy(c => c.ColumnNo)
                                .ThenBy(c => c.LayerNo)
                                .FirstOrDefault();


                    if (allotCell == null)//如果没有找到匹配
                    {
                        //寻找一个整深度都是空的仓位
                        var cellsIsMaxDepths = cellQuery.Where(r => r.IsMaxDepth == true && r.Status == 1 && r.FullStatus == 0 && r.IsLock == false && r.BusinessType == 0 && rwIds.Contains(r.RoutewayId)).ToList();

                        if (cellsIsMaxDepths is not null || cellsIsMaxDepths.Count() > 0)
                        {
                            allotCell = cellsIsMaxDepths.OrderByDescending(c => c.DepthIndex)
                                .ThenBy(c => c.LineNo)
                                .ThenBy(c => c.ColumnNo)
                                .ThenBy(c => c.LayerNo)
                                .FirstOrDefault();
                            //OrderBy(c => c.LineNo)
                            //   .ThenBy(c => c.ColumnNo)
                            //   .ThenBy(c => c.LayerNo)
                            //   .ThenByDescending(c => c.DepthIndex)
                            //   .FirstOrDefault();
                            if (allotCell != null)
                            {
                                return allotCell;
                            }
                        }
                        int i = 0;
                        int count = routewayList.Count;
                        int? stationSort = srcStation.StationSort;
                        string key = stationSort.GetValueOrDefault() + "_routeway";
                        do
                        {
                            //对巷道进行排序，均分原则
                            string allotCode = GlobalManager.AvgAllot(key, routewayCodes);
                            if (string.IsNullOrEmpty(allotCode))
                            {
                                errorMsg = "无可用巷道";
                                return null;
                            }
                            TRouteway routeway = routewayList.Find(t => t.Code == allotCode);
                            if (routeway == null)
                            {
                                errorMsg = "无可用巷道";
                                return null;
                            }
                            List<int> enabledarea = areasList.Select(t => t.Id).ToList();//只取库区id
                            List<int> enabledShelves = shelvesList.Where(s => s.RoutewayId == routeway.Id && enabledarea.Contains(s.AreaId)).Select(t => t.Id).ToList();//只取货架id
                            if (enabledShelves is null)
                            {
                                errorMsg = "无可用货架";
                                return null;
                            }
                            var cells = cellQuery.Where(t => t.Status == (int)EmCellStatus.Normal && t.FullStatus == 0 && t.IsLock == false && t.BusinessType == 0 && t.RoutewayId == routeway.Id && enabledShelves.Contains(t.ShelfId)).ToList();
                            //if (!string.IsNullOrEmpty(logicalPartCode))
                            //{
                            //    cells = cells.Where(t => t.LogicalPartCode == logicalPartCode).ToList();
                            //}
                            //优先找距离最短、深度最深的货位

                            allotCell = cells.OrderByDescending(c => c.DepthIndex)
                                .ThenBy(c => c.LineNo)
                                .ThenBy(c => c.ColumnNo)
                                .ThenBy(c => c.LayerNo)
                                .FirstOrDefault();
                            #region 注释掉的
                            //if (allotCell != null)
                            //{
                            ////当分配了一个双深位浅位仓位时，需要判断深位是否是同种物料批次，此处是为了校验，正常不会进入该条件。先保留
                            //if (allotCell.DepthIndex == 0 && allotCell.IsMaxDepth == false)
                            //{
                            //    //CellModel depthCell = cellService.GetCell(context, new CellCriteriaModel { IsMaxDepth = true, DepthIndex = 1, LineNO = cellList[0].LineNO, LayerNO = cellList[0].LayerNO, ColumnNO = cellList[0].ColumnNO });
                            //    CellModel depthCell = cellQuery.Where(t => t.IsMaxDepth == true && t.DepthIndex == 1 && t.LineNO == allotCell.LineNO && t.LayerNO == allotCell.LayerNO && t.ColumnNO == allotCell.ColumnNO).FirstOrDefault();
                            //    if (depthCell.Status == EmCellStatus.Normal)
                            //    {
                            //        //深位如果有货
                            //        if (depthCell.FullStatus == 0)
                            //        {
                            //            errorMsg = "仓位分配逻辑有误或数据有误";
                            //            return false;
                            //        }
                            //        InventoryModel inventory = context.Query<InventoryModel>().Where(t => t.LocationId == depthCell.Id).FirstOrDefault();
                            //        if (inventory == null)
                            //        {
                            //            errorMsg = "库存数据有误";
                            //            return false;
                            //        }
                            //        if (inventory.MaterialId != materialId || inventory.MaterialKeyId != materialKeyId||inventory.QualityState!= qualityState)
                            //        {
                            //            errorMsg = "库存数据有误";
                            //            return false;
                            //        }
                            //    }
                            //}
                            //}
                            #endregion
                            if (allotCell != null)
                            {
                                break;
                            }
                            i++;
                        } while (i < count);
                    }
                    if (hasCell && allotCell == null)
                    {
                        int sameMaterialCount = 0;
                        if (rwIds.Count > 0)
                        {
                            if (!string.IsNullOrEmpty(logicalPartCode))
                            {
                                var sameMaterial = (from cell in cellQuery
                                                    join inv in inventoryQuery
                                                    on cell.Id equals inv.LocationId
                                                    where rwIds.Contains(cell.RoutewayId)
                                                    && inv.MaterialId == materialId
                                                    && inv.MaterialKeyId == materialKeyId
                                                    && cell.LogicalPartCode == logicalPartCode
                                                    && cellQuery.Where(ct => ct.LayerNo == cell.LayerNo
                                                    && ct.LineNo == cell.LineNo
                                                    && ct.ColumnNo == cell.ColumnNo
                                                    && ct.Status == (int)EmCellStatus.Normal
                                                    && ct.IsLock == false && ct.BusinessType == 0
                                                    && ct.FullStatus == 0).Any()
                                                    && cell.IsLock == false && inv.Status == 1
                                                    && cell.BusinessType == 0
                                                    select cell
                                          ).ToList();
                                sameMaterialCount = sameMaterial.Count();
                            }
                            else
                            {
                                var sameMaterial = (from cell in cellQuery
                                                    join inv in inventoryQuery
                                                    on cell.Id equals inv.LocationId
                                                    where rwIds.Contains(cell.RoutewayId)
                                                    && inv.MaterialId == materialId
                                                    && inv.MaterialKeyId == materialKeyId
                                                    && cellQuery.Where(ct => ct.LayerNo == cell.LayerNo
                                                    && ct.LineNo == cell.LineNo
                                                    && ct.ColumnNo == cell.ColumnNo
                                                    && ct.Status == (int)EmCellStatus.Normal
                                                    && ct.IsLock == false && ct.BusinessType == 0
                                                    && ct.FullStatus == 0).Any()
                                                    && cell.IsLock == false && inv.Status == 1
                                                    && cell.BusinessType == 0
                                                    select cell
                                         ).ToList();
                                sameMaterialCount = sameMaterial.Count();
                            }
                        }
                        waitIndex++;
                        if (waitIndex > 20)//最多等待10分钟
                        {
                            break;
                        }
                        hasCell = sameMaterialCount > 0;
                        if (sameMaterialCount > 0)
                        {
                            Thread.Sleep(30000);
                        }
                    }
                    else
                    {
                        if (!hasCell)
                        {
                            errorMsg = "没有仓位可分配";
                        }
                    }
                } while (hasCell && allotCell == null);//没有分配到仓位，同时又有仓位时，则说明深位还未完成，需等待

                return allotCell;
            }
            catch (Exception ex)
            {
                errorMsg = "未知异常:" + ex.Message;
                return null;
            }
        }

        public TCell AllocateCellNew(TStation srcStation, int materialId, int materialKeyId, int? qualityState, int heightType, out string errorMsg, string logicalPartCode = "")
        {
            errorMsg = "";
            if (materialId <= 0 || materialKeyId <= 0)
            {
                return null;
            }
            TCell allotCell = null;
            try
            {
                TDictItem commonlogicalPartType = Context.TDictItems.AsNoTracking().Where(t => t.TypeCode == "LogicPartType" && t.ItemCode == "Common").FirstOrDefault();
                bool hasCell = false;
                int waitIndex = 0;
                string lineOrder = "ASC";
                do
                {
                    var routewayQuery = Context.TRouteways.AsNoTracking().ToList(); //获取所有巷道
                    var cellQuery = Context.TCells.AsNoTracking().ToList(); //获取所以仓位
                    var inventoryQuery = Context.TInventory.AsNoTracking().ToList(); //获取库存数据
                    var shelves = Context.TShelves.AsNoTracking().ToList(); // 获取所有货架
                    if (srcStation.WhId > 0) //库房id不等于空的话会根据库房id去筛选
                    {
                        routewayQuery = routewayQuery.Where(zw => zw.WhId == srcStation.WhId).ToList();
                        cellQuery = cellQuery.Where(zw => zw.WhId == srcStation.WhId).ToList();
                        inventoryQuery = inventoryQuery.Where(zw => zw.WarehouseId == srcStation.WhId).ToList();
                        shelves = shelves.Where(s => s.WhId == srcStation.WhId).ToList();
                    }
                    List<TRouteway> routewayList = routewayQuery.Where(r => r.Status == 1).ToList();//查询出可以用的巷道
                    var shelvesList = shelves.Where(s => s.Status == 1).ToList(); //查询出可用的巷道
                    if (!string.IsNullOrEmpty(logicalPartCode) && routewayList != null && routewayList.Count > 0 && shelvesList != null && shelvesList.Count > 0)
                    {
                        List<int> enabledRoutewayIds = routewayList.Select(t => t.Id).ToList();//只取巷道id
                        List<int> enabledShelves = shelvesList.Select(t => t.Id).ToList();//只取货架id
                        List<int> routewayIds = cellQuery.Where(t => t.Status == (int)EmCellStatus.Normal && t.BusinessType == 0 && t.IsLock == false && t.FullStatus == 0 && t.LogicalPartCode == logicalPartCode && enabledRoutewayIds.Contains((int)t.RoutewayId) && enabledShelves.Contains(t.ShelfId)).Select(t => t.RoutewayId).Distinct().ToList(); //只取巷道id
                        if (routewayIds == null || routewayIds.Count == 0)
                        {
                            logicalPartCode = commonlogicalPartType == null ? "" : commonlogicalPartType.ItemCode;
                            routewayIds = cellQuery.Where(t => t.Status == (int)EmCellStatus.Normal && t.BusinessType == 0 && t.IsLock == false && t.FullStatus == 0 && t.LogicalPartCode == logicalPartCode && enabledRoutewayIds.Contains(t.RoutewayId) && enabledShelves.Contains(t.ShelfId)).Select(t => t.RoutewayId).Distinct().ToList();
                        }
                        if (routewayIds != null && routewayIds.Count > 0)
                        {
                            routewayList = routewayList.Where(t => routewayIds.Contains(t.Id)).ToList();
                        }
                    }
                    if (routewayList == null || routewayList.Count == 0)
                    {
                        errorMsg = "无可用巷道";
                        return null;
                    }

                    hasCell = true;

                    //只取巷道编号
                    List<string> routewayCodes = routewayList.OrderBy(t => t.DisplayOrder).Select(t => t.Code).ToList();
                    if (lineOrder == "DESC")
                    {
                        routewayCodes = routewayList.OrderByDescending(t => t.DisplayOrder).Select(t => t.Code).ToList();
                    }

                    List<int?> rwIds = routewayList.Select(t => (int?)t.Id).ToList();
                    //找到此巷道同种物料同批次的，且浅位无货深位有货的
                    var depthCellQuery = (from cell in cellQuery
                                          join inv in inventoryQuery
                                          on cell.Id equals inv.LocationId
                                          where rwIds.Contains(cell.RoutewayId)
                                          && inv.MaterialId == materialId
                                          && inv.MaterialKeyId == materialKeyId
                                          && cell.Status == (int)EmCellStatus.Normal
                                          && cell.IsLock == false && inv.Status == 1
                                          && cell.BusinessType == 0
                                          select cell
                                         );
                    var depthLockCellQuery = (from cell in cellQuery
                                              join inv in inventoryQuery
                                              on cell.Id equals inv.LocationId
                                              where rwIds.Contains(cell.RoutewayId)
                                              && inv.MaterialId == materialId
                                              && inv.MaterialKeyId == materialKeyId
                                              && (cell.Status != (int)EmCellStatus.Normal
                                              || cell.IsLock == true || inv.Status != 1)
                                              select cell
                                        );
                    var celllist = cellQuery.Where(t => t.Status == (int)EmCellStatus.Normal && t.FullStatus == 0 && t.IsLock == false && t.BusinessType == 0 && rwIds.Contains(t.RoutewayId));

                    celllist = celllist.Where(t => depthCellQuery.Where(dc => dc.LayerNo == t.LayerNo && dc.LineNo == t.LineNo && dc.ColumnNo == t.ColumnNo).Any());

                    celllist = celllist.Where(t => !depthLockCellQuery.Where(dc => dc.LayerNo == t.LayerNo && dc.LineNo == t.LineNo && dc.ColumnNo == t.ColumnNo).Any()).ToList();
                    if (!string.IsNullOrEmpty(logicalPartCode))
                    {
                        celllist = celllist.Where(t => t.LogicalPartCode == logicalPartCode).ToList();
                    }
                    //优先找同种物料、距离最短、深度最深的货位
                    allotCell = celllist.OrderBy(c => c.LineNo)
                        .ThenBy(c => c.ColumnNo)
                        .ThenBy(c => c.LayerNo)
                        .ThenBy(c => c.DistanceValue)
                        .FirstOrDefault();
                    if (allotCell == null)//如果没有找到匹配
                    {
                        int i = 0;
                        int count = routewayList.Count;
                        int? stationSort = srcStation.StationSort;
                        string key = stationSort.GetValueOrDefault() + "_routeway";
                        do
                        {
                            //对巷道进行排序，均分原则
                            string allotCode = GlobalManager.AvgAllot(key, routewayCodes);
                            if (string.IsNullOrEmpty(allotCode))
                            {
                                errorMsg = "无可用巷道";
                                return null;
                            }
                            TRouteway routeway = routewayList.Find(t => t.Code == allotCode);
                            if (routeway == null)
                            {
                                errorMsg = "无可用巷道";
                                return null;
                            }
                            List<int> enabledShelves = shelvesList.Where(s => s.RoutewayId == routeway.Id).Select(t => t.Id).ToList();//只取货架id
                            if (enabledShelves is null)
                            {
                                errorMsg = "无可用货架";
                                return null;
                            }
                            var cells = cellQuery.Where(t => t.Status == (int)EmCellStatus.Normal && t.FullStatus == 0 && t.IsLock == false && t.BusinessType == 0 && t.RoutewayId == routeway.Id && enabledShelves.Contains(t.ShelfId)).ToList();
                            if (!string.IsNullOrEmpty(logicalPartCode))
                            {
                                cells = cells.Where(t => t.LogicalPartCode == logicalPartCode).ToList();
                            }
                            //优先找距离最短、深度最深的货位

                            allotCell = cells.OrderBy(c => c.LineNo)
                                .ThenBy(c => c.ColumnNo)
                                .ThenBy(c => c.LayerNo)
                                .ThenBy(c => c.DistanceValue)
                        .FirstOrDefault();
                            #region 注释掉的
                            //if (allotCell != null)
                            //{
                            ////当分配了一个双深位浅位仓位时，需要判断深位是否是同种物料批次，此处是为了校验，正常不会进入该条件。先保留
                            //if (allotCell.DepthIndex == 0 && allotCell.IsMaxDepth == false)
                            //{
                            //    //CellModel depthCell = cellService.GetCell(context, new CellCriteriaModel { IsMaxDepth = true, DepthIndex = 1, LineNO = cellList[0].LineNO, LayerNO = cellList[0].LayerNO, ColumnNO = cellList[0].ColumnNO });
                            //    CellModel depthCell = cellQuery.Where(t => t.IsMaxDepth == true && t.DepthIndex == 1 && t.LineNO == allotCell.LineNO && t.LayerNO == allotCell.LayerNO && t.ColumnNO == allotCell.ColumnNO).FirstOrDefault();
                            //    if (depthCell.Status == EmCellStatus.Normal)
                            //    {
                            //        //深位如果有货
                            //        if (depthCell.FullStatus == 0)
                            //        {
                            //            errorMsg = "仓位分配逻辑有误或数据有误";
                            //            return false;
                            //        }
                            //        InventoryModel inventory = context.Query<InventoryModel>().Where(t => t.LocationId == depthCell.Id).FirstOrDefault();
                            //        if (inventory == null)
                            //        {
                            //            errorMsg = "库存数据有误";
                            //            return false;
                            //        }
                            //        if (inventory.MaterialId != materialId || inventory.MaterialKeyId != materialKeyId||inventory.QualityState!= qualityState)
                            //        {
                            //            errorMsg = "库存数据有误";
                            //            return false;
                            //        }
                            //    }
                            //}
                            //}
                            #endregion
                            if (allotCell != null)
                            {
                                break;
                            }
                            i++;
                        } while (i < count);
                    }
                    if (hasCell && allotCell == null)
                    {
                        int sameMaterialCount = 0;
                        if (rwIds.Count > 0)
                        {
                            if (!string.IsNullOrEmpty(logicalPartCode))
                            {
                                var sameMaterial = (from cell in cellQuery
                                                    join inv in inventoryQuery
                                                    on cell.Id equals inv.LocationId
                                                    where rwIds.Contains(cell.RoutewayId)
                                                    && inv.MaterialId == materialId
                                                    && inv.MaterialKeyId == materialKeyId
                                                    && cell.LogicalPartCode == logicalPartCode
                                                    && cellQuery.Where(ct => ct.LayerNo == cell.LayerNo
                                                    && ct.LineNo == cell.LineNo
                                                    && ct.ColumnNo == cell.ColumnNo
                                                    && ct.Status == (int)EmCellStatus.Normal
                                                    && ct.IsLock == false && ct.BusinessType == 0
                                                    && ct.FullStatus == 0).Any()
                                                    && cell.IsLock == false && inv.Status == 1
                                                    && cell.BusinessType == 0
                                                    select cell
                                          ).ToList();
                                sameMaterialCount = sameMaterial.Count();
                            }
                            else
                            {
                                var sameMaterial = (from cell in cellQuery
                                                    join inv in inventoryQuery
                                                    on cell.Id equals inv.LocationId
                                                    where rwIds.Contains(cell.RoutewayId)
                                                    && inv.MaterialId == materialId
                                                    && inv.MaterialKeyId == materialKeyId
                                                    && cellQuery.Where(ct => ct.LayerNo == cell.LayerNo
                                                    && ct.LineNo == cell.LineNo
                                                    && ct.ColumnNo == cell.ColumnNo
                                                    && ct.Status == (int)EmCellStatus.Normal
                                                    && ct.IsLock == false && ct.BusinessType == 0
                                                    && ct.FullStatus == 0).Any()
                                                    && cell.IsLock == false && inv.Status == 1
                                                    && cell.BusinessType == 0
                                                    select cell
                                         ).ToList();
                                sameMaterialCount = sameMaterial.Count();
                            }
                        }
                        waitIndex++;
                        if (waitIndex > 20)//最多等待10分钟
                        {
                            break;
                        }
                        hasCell = sameMaterialCount > 0;
                        if (sameMaterialCount > 0)
                        {
                            Thread.Sleep(30000);
                        }
                    }
                    else
                    {
                        if (!hasCell)
                        {
                            errorMsg = "没有仓位可分配";
                        }
                    }
                } while (hasCell && allotCell == null);//没有分配到仓位，同时又有仓位时，则说明深位还未完成，需等待

                return allotCell;
            }
            catch (Exception ex)
            {
                errorMsg = "未知异常:" + ex.Message;
                return null;
            }
        }

        public List<TCell> GetCellByCell(List<TCell> cell)
        {
            if (cell == null || cell.Count() == 0)
            {
                return new List<TCell>();
            }
            var cellList = Context.TCells.AsNoTracking().ToList();
            var resList = new List<TCell>();
            foreach (var item in cell)
            {
                if (item.Remark == null || item.Remark == "")
                {
                    continue;
                }
                var cells = cellList.Where(s => s.Remark == item.Remark);
                if (cells != null && cells.Count() > 0)
                {
                    resList.AddRange(cells);
                }

            }
            return resList;
        }

        public List<SelectListItem> GetCellLayer()
        {
            List<int> allLayer = Context.TCells.Select(t => t.LayerNo).Distinct().ToList();
            List<SelectListItem> selectListItems = new List<SelectListItem>();
            foreach (var item in allLayer)
            {
                selectListItems.Add(new SelectListItem()
                {
                    Text = $"{item}层",
                    Value = item
                });
            }
            return selectListItems;
        }

        public List<TCell> GetCellByLayer(int layerNo)
        {
            return Context.TCells.Where(x => x.LayerNo == layerNo).ToList();
        }
        public TCell GetCellById(int cellId) 
        {
            return Context.TCells.Where(x => x.Id == cellId).FirstOrDefault();
        } 
        public TInventory GetInventoryByCell(int cellId) 
        {
            return Context.TInventory.Where(x => x.LocationId == cellId).FirstOrDefault();
        }
    }

    public record Pcl(int lineNo, int layerNo, int columnNo);

}